package com.dingreading.cloud.ssxcx.service.impl;

import com.dingreading.cloud.ssxcx.dto.SubjectsDto;
import com.dingreading.cloud.ssxcx.entity.Subjects;
import com.dingreading.cloud.ssxcx.entity.table.SubjectsTableDef;
import com.dingreading.cloud.ssxcx.mapper.SubjectsMapper;
import com.dingreading.cloud.ssxcx.service.SubjectsService;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 *  服务层实现。
 *
 * @author EDY
 * @since 2025-08-09
 */
@Service
public class SubjectsServiceImpl extends BaseServiceImpl<SubjectsMapper, Subjects, SubjectsTableDef> implements SubjectsService {

    @Override
    protected SubjectsTableDef getTable() {
        return SubjectsTableDef.subjects;
    }

    @Override
    public List<SubjectsDto> getByprojectUids(Set<String> subjectUids) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(table.uid.in(subjectUids))
                .orderBy(table.id.asc());
        return getMapper().selectListByQueryAs(queryWrapper, SubjectsDto.class);
    }

    @Override
    public List<SubjectsDto> getBySubjectUids(Set<String> subjectUids) {
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.uid.in(subjectUids))
                .and(table.enabled.eq(1));
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.id.asc());
        List<SubjectsDto> subjectsDtos = getMapper().selectListByQueryAs(queryWrapper, SubjectsDto.class);

        if (CollectionUtils.isEmpty(subjectsDtos)) {
            return new ArrayList<>();
        }

        // 如果子级还有下面的层级继续查询
        List<String> nodePaths = subjectsDtos.stream()
                .filter(dto -> {
                    boolean isLevelEndValid = dto.getLevelEnd() != null && dto.getLevelEnd() != 1;
                    boolean isLevelIndexValid = dto.getLevelIndex() != null && dto.getLevelIndex() != 0 && dto.getLevelIndex() != 1;
                    return isLevelEndValid && isLevelIndexValid;
                })
                .map(SubjectsDto::getNodes)
                .filter(StringUtils::isNotBlank)
                .distinct()
                .collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(nodePaths)){
            QueryCondition queryCondition = QueryCondition.createEmpty();
            for (String nodePath : nodePaths){
                queryCondition.or(table.nodes.like(nodePath + "%"));
            }

            QueryWrapper nodesWrapper = QueryWrapper.create()
                    .where(queryCondition);
            List<SubjectsDto> subjectsDtosByNodes = getMapper().selectListByQueryAs(nodesWrapper, SubjectsDto.class);

            if (CollectionUtils.isNotEmpty(subjectsDtosByNodes)) {
                Map<String, SubjectsDto> resultMap = new LinkedHashMap<>();

                subjectsDtos.forEach(dto -> resultMap.put(dto.getUid(), dto));

                subjectsDtosByNodes.forEach(dto -> resultMap.putIfAbsent(dto.getUid(), dto));

                return new ArrayList<>(resultMap.values());
            }
        }
        return subjectsDtos;
    }

    @Override
    public List<Subjects> getBySubjectIds(Set<Long> uniqueSubjectIds) {
        QueryCondition queryCondition = QueryCondition.createEmpty()
                .and(table.id.in(uniqueSubjectIds))
                .and(table.enabled.eq(1));
        return getMapper().selectListByCondition(queryCondition);
    }

    @Override
    public Subjects getByUid(String subjectUid) {
        return getMapper().selectOneByCondition(table.uid.eq(subjectUid));
    }
}
